import CryptoJS from 'crypto-js'

/**
 * 使用PBKDF2派生密钥
 * @param password 主密码
 * @param salt 盐值
 * @param iterations 迭代次数
 * @param keySize 密钥长度（字节）
 */
export const deriveKey = (
  password: string,
  salt: string,
  iterations: number = 10000,
  keySize: number = 32
): string => {
  try {
    const saltWords = CryptoJS.enc.Hex.parse(salt)

    const key = CryptoJS.PBKDF2(password, saltWords, {
      keySize: keySize / 4, // CryptoJS的keySize是以32位字为单位
      iterations: iterations,
      hasher: CryptoJS.algo.SHA256
    })

    return key.toString(CryptoJS.enc.Hex)

  } catch (error) {
    throw new Error(`密钥派生失败: ${error}`)
  }
}

/**
 * 生成随机密钥
 * @param length 密钥长度（字节）
 */
export const generateKey = (length: number = 32): string => {
  return CryptoJS.lib.WordArray.random(length).toString(CryptoJS.enc.Hex)
}

/**
 * 生成随机盐值
 * @param length 盐值长度（字节）
 */
export const generateSalt = (length: number = 16): string => {
  return CryptoJS.lib.WordArray.random(length).toString(CryptoJS.enc.Hex)
}

/**
 * 哈希密码（用于验证）
 * @param password 密码
 * @param salt 盐值
 * @param iterations 迭代次数
 */
export const hashPassword = (
  password: string,
  salt: string,
  iterations: number = 10000
): string => {
  try {
    const saltWords = CryptoJS.enc.Hex.parse(salt)

    const hash = CryptoJS.PBKDF2(password, saltWords, {
      keySize: 256 / 32, // 256位
      iterations: iterations,
      hasher: CryptoJS.algo.SHA256
    })

    return hash.toString(CryptoJS.enc.Hex)

  } catch (error) {
    throw new Error(`密码哈希失败: ${error}`)
  }
}

/**
 * 验证密码
 * @param password 输入的密码
 * @param hash 存储的哈希值
 * @param salt 盐值
 * @param iterations 迭代次数
 */
export const verifyPassword = (
  password: string,
  hash: string,
  salt: string,
  iterations: number = 10000
): boolean => {
  try {
    const computedHash = hashPassword(password, salt, iterations)
    return computedHash === hash
  } catch (error) {
    return false
  }
}